home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr01
/
jock.zip
/
TOTDOC11.ZIP
/
CHAPT17.TXT
< prev
next >
Wrap
Text File
|
1991-02-11
|
15KB
|
301 lines
Replacing
the
Screen
Writer
"I don't want to achieve immortality through my work, I want to achieve
immortality by not dying."
Woody Allen
The Toolkit uses some assembly language routines for writing to the
screen, as well as for moving blocks of data to and from the screen.
The routines are optimized for maximum speed, and by-pass BIOS, i.e.
they write directly to the video area of memory. If you are using a
non-standard display device, such as a palmtop computer, or you don't
like the (1..80,1..25) coordinate scheme, or for whatever other reason,
you can develop your own screen writing code to meet your custom needs.
In this chapter you will learn how to create an object to replace the
Toolkit's screen writing routines.
Understanding ScreenOBJ and WriteOBJ
Before discussing how to replace the Toolkit's methods, you need to
understand how those methods work. Bear in mind that your replacement
algorithms may need to write to virtual screens as well as to the
physical screen.
The ScreenOBJ object is the primary Toolkit object for managing screen
and video related activity. The global instance Screen is automatically
initialized when you use the totFAST unit, and you should use the
Screen instance for all writing to the visible display. Additional
ScreenOBJ instances can be used to manage virtual (or non-visible)
screens. The method SAVE is used to save a copy of the visible screen,
and the method CREATE is used to create an empty virtual screen with
maximum dimensions of 255 rows by 255 columns. All or part of a virtual
screen can subsequently be displayed on the visible screen.
Each ScreenOBJ instance includes a pointer to a WriteOBJ object. Wri-
teOBJ actually performs the core screen writing functions. For example,
when you call ScreenOBJ's method WriteAT, behind the scenes the Toolkit
calls the WriteOBJ method WriteAT. By instructing ScreenOBJ to point to
a different WriteOBJ object you can change how screen tasks are per-
formed. In other words, by creating a new WriteOBJ object, you change
how the Toolkit accesses the video functions.
The two step process is to create a descendant of WriteOBJ, and then
instruct all ScreenOBJ instances to use this new object.
17-2 Extending the Toolkit
--------------------------------------------------------------------------------
Replacing WriteOBJ
The primary functions of WriteOBJ are to write to the screen, to move
blocks of data to and from the screen, to position the cursor, to
manage window settings, and to change the display attribute of a rect-
angular area of the screen.
The declaration of WriteOBJ is as follows:
WritePtr = ^WriteOBJ;
WriteOBJ = object
vWidth: byte; {how wide is screen}
vScreenPtr: pointer; {memory location of screen data}
vWindow: tByteCoords; {active screen area}
vWindowOn: boolean; {is window area active}
vWindowIgnore: boolean; {ignore window settings}
{methods...}
Constructor Init;
procedure SetScreen(var P:Pointer; W:byte);
function WindowOff: boolean;
procedure SetWinIgnore(On:Boolean);
procedure WindowOn;
procedure WindowCoords(var Coords: tByteCoords);
function WindowActive: boolean;
function WinX: byte;
function WinY: byte;
procedure GetWinCoords(var X1,Y1,X2,Y2:byte);
procedure WriteAT(X,Y,attr:byte;Str:string); VIRTUAL;
procedure WritePlain(X,Y:byte;Str:string); VIRTUAL;
procedure Write(Str:string); VIRTUAL;
procedure WriteLn(Str:string); VIRTUAL;
procedure GotoXY(X,Y: word); VIRTUAL;
function WhereX: word; VIRTUAL;
function WhereY: word; VIRTUAL;
procedure SetWindow(X1,Y1,X2,Y2: byte); VIRTUAL;
procedure ResetWindow; VIRTUAL;
procedure ChangeAttr(Col,Row,Att:byte;Len:word); VIRTUAL;
procedure MoveFromScreen(var Source,Dest;Length:Word); VIRTUAL;
procedure MoveToScreen(var Source,Dest; Length:Word); VIRTUAL;
procedure Clear(Att:byte;Ch:char); VIRTUAL;
destructor Done; VIRTUAL;
end; {WriteOBJ}
WriteOBJ's data describes the size and memory location of the screen,
and the status of the window settings.
Replacing the Screen Writer 17-3
--------------------------------------------------------------------------------
vWidth is a byte variable which identifies the width of the screen.
vScreenPtr is a pointer to the start of the screen display memory area.
The memory is organized into byte pairs, like actual video display
memory - the first byte is the attribute of a character and the second
byte is the ASCII code of the character. The associated ScreenOBJ
instance allocates the necessary memory and calls the WriteOBJ method
SetScreen to update the vWidth and vScreenPtr variables.
The other variables provide information about the screen's active win-
dow. vWindow is a record describing the (X1,Y1) and (X2,Y2) active
window coordinates. vWindowOn and vWindowIgnore are two boolean
variables which indicate whether the window settings are active. If
vWindowOn is false or vWindowIgnore is true, the WriteOBJ screen writ-
ing methods should ignore the current window settings.
The virtual methods shown in the WriteOBJ declaration represent the
heart of the screen writing routines. The table below describes their
specific purpose.
Method Description
WriteAT(X,Y,attr:byte;Str:string); Writes to the screen at (X,Y)
using the specified attribute.
WritePlain(X,Y:byte;Str:string); Writes to the screen at (X,Y)
using that region's attribute.
Write(Str:string); Writes at the current cursor
position like Turbo's Write.
WriteLn(Str:string); Write at the current cursor posi-
tion like Turbo's WriteLn.
GotoXY(X,Y: word); Positions the cursor at (X,Y).
WhereX: word; Returns the cursor's X coordi-
nate.
WhereY: word;
Returns the cursor's Y coordi-
SetWindow(X1,Y1,X2,Y2: byte); nate.
ResetWindow; Sets the window coordinates to
specified coordinates.
ChangeAttr(Col,Row,Att:byte; Sets the window coordinates to
Len:word); entire screen.
MoveFromScreen(var Source,Dest; Changes the display attribute to
Len:Word); Att starting at (X,Y) for Len
bytes.
Moves a block of memory from
MoveToScreen(var Source,Dest; Source to Dest, assuming Source
Len:Word); is the visible screen. Len repre-
Clear(Att:byte;Ch:char); sents the number of words (not
17-4 Extending the Toolkit
--------------------------------------------------------------------------------
bytes) to move.
As above, but assumes Dest is the
Done; visible screen.
Clears a rectangular area of the
display to the specified attrib-
ute and replaces all characters
with Ch.
Disposes of the object.
To develop your own WriteOBJ object, you should create a descendant of
WriteOBJ, and thanks to inheritance, you can replace as little as one
procedure or as many as all of them.
The file EXTSCR1.PAS is a demonstration unit which creates a new
object. The new object is called MonoWriteOBJ, and the objective is to
force the Toolkit to use the attribute white-on-black, regardless of
the attribute specified. The declaration of MonoWriteOBJ is as follows:
Unit ExtFast;
{$I TOTFLAGS.INC}
INTERFACE
uses DOS, CRT, totFAST;
TYPE
MonoWriteOBJ = object (WriteOBJ)
constructor Init;
procedure WriteAT(X,Y,attr:byte;Str:string); VIRTUAL;
procedure ChangeAttr(X,Y,Att:byte;Len:word); VIRTUAL;
procedure Clear(Att:byte;Ch:char); VIRTUAL;
destructor Done; VIRTUAL;
end; {MonoWriteOBJ}
IMPLEMENTATION
constructor MonoWriteOBJ.Init;
{}
begin
WriteOBJ.Init;
TextColor(white);
Textbackground(black);
end; {MonoWriteOBJ.Init}
procedure MonoWriteOBJ.WriteAT(X,Y,attr:byte;Str:string);
{}
begin
WriteOBJ.WriteAT(X,Y,white,Str);
end; {MonoWriteOBJ.WriteAT}
Replacing the Screen Writer 17-5
--------------------------------------------------------------------------------
procedure MonoWriteOBJ.ChangeAttr(X,Y,Att:byte;Len:word);
{}
begin
WriteOBJ.ChangeAttr(X,Y,white,Len);
end; {MonoWriteOBJ.ChangeAttr}
procedure MonoWriteOBJ.Clear(Att:byte;Ch:char);
{}
begin
WriteOBJ.Clear(white,Ch);
end; {MonoWriteOBJ.Clear}
destructor MonoWriteOBJ.Done;
{}
begin
WriteOBJ.Done;
end; {MonoWriteOBJ.Done}
end.
MonoWriteOBJ redefines the three primary methods which control display
attributes. It intercepts the requested attribute and always substi-
tutes the attribute white.
If you want to modify the way the Toolkit writes to the physical
screen, but are satisfied with the virtual screen routines, then your
unit should use the totSYS unit, and the revised methods should use the
following statement to determine whether the instance is pointing to
the visible screen:
if vScreenPtr = Monitor^.BaseOfScreen then
{new visible screen routines}
else {virtual screen}
{call equivalent WriteOBJ method};
Using the Method AssignWriteOBJ
Having created your new object, you must instruct the Toolkit to use
it. This is achieved by initializing your object, and then calling the
ScreenOBJ method AssignWriteOBJ method. For example:
Screen.AssignWriteOBJ(WhiteWrite);
Any virtual screens you create must be assigned the new WriteOBJ object
individually in the same manner. For example:
Save3.AssignWriteOBJ(WhiteWrite);
17-6 Extending the Toolkit
--------------------------------------------------------------------------------
The demo program, EXTDEM3.PAS, listed below, shows the new ExtFast unit
in use. This program is actually an adaptation of DEMBR1, which uses
MonoWriteOBJ in preference to WriteOBJ. If you run it, you will see
that the entire display uses white on black, even though other attrib-
utes are specified.
Program ExtendedDemoThree;
{EXTDEM3 - this program shows how to use the MonoWriteOBJ object
developed in the ExtFast unit. The demo is actually a simple
adaptation of the browse demo file DEMBR1}
Uses DOS,CRT,
totINPUT, totFAST,totLIST, totSTR, ExtFast;
var
WhiteWrite: MonoWriteOBJ;
BWin: BrowseArrayOBJ;
StringList: array[1..26] of string[100];
I : integer;
begin
WhiteWrite.Init;
Screen.AssignWriteOBJ(WhiteWrite);
for I := 1 to 26 do {first assign something to the string array}
StringList[I] := 'Line '+IntToStr(I)+': '+replica-
te(80,char(I+64));
ShadowTot^.SetShadowStyle(downright,red,chr(219));
Screen.Clear(green,' '); {paint the screen}
Key.SetFast;
Key.SetClick(true);
with BWin do
begin
Init;
AssignList(StringList,26,100);
Go;
Done;
end;
end.